#include "Line.h"
#include <math.h>

Line::Line()
{
	point0 = SGD::Point(-1.0f, -1.0f);
	point1 = point0;
}

Line::Line(SGD::Point p0, SGD::Point p1)
{
	point0 = p0;
	point1 = p1;
}

Line::~Line()
{
}

SGD::Vector Line::Convert(SGD::Point point)
{
	SGD::Vector u;
	u.x = point.x;
	u.y = point.y;
	return u;
}

SGD::Point Line::Convert(SGD::Vector vector)
{
	SGD::Point p;
	p.x = vector.x;
	p.y = vector.y;
	return p;
}

bool Line::IntersectionPoint(Line otherLine, SGD::Point& intersection)
{
	SGD::Vector p = Convert(point0);
	SGD::Vector q = Convert(otherLine.point0);
	SGD::Vector r = Convert(point1) - p;
	SGD::Vector s = Convert(otherLine.point1) - q;
	float t = CrossProduct((q - p), s) / CrossProduct(r, s);
	float u = CrossProduct((q - p), r) / CrossProduct(r, s);

	if (CrossProduct(r, s) == 0 && CrossProduct((q - p), r) == 0)	// Lines are collinear
	{
		if (0 <= (q - p).ComputeDotProduct(r) && (q - p).ComputeDotProduct(r) <= r.ComputeDotProduct(r)
			|| 0 <= (p - q).ComputeDotProduct(s) && (p - q).ComputeDotProduct(s) <= s.ComputeDotProduct(s)) // Lines are overlapping
		{
			intersection = point0;
			return true;
		}
		else if (!(0 <= (q - p).ComputeDotProduct(r) && (q - p).ComputeDotProduct(r) <= r.ComputeDotProduct(r))
			&& !(0 <= (p - q).ComputeDotProduct(s) && (p - q).ComputeDotProduct(s) <= s.ComputeDotProduct(s))) // Lines are collinear, but disjointed
		{
			return false;
		}
	}
	else if (CrossProduct(r, s) == 0) // Lines are parallel and non-intersecting
	{
		return false;
	}
	else if (0 <= t && t <= 1 && 0 <= u && u <= 1)
	{
		SGD::Vector x = p + (r * t);
		SGD::Vector y = q + (s * u);
		intersection = Convert(x);
		return true;
	}
	else
		return false;
	return false;
}

float Line::CrossProduct(SGD::Vector u, SGD::Vector v)
{
	return u.x * v.y - u.y * v.x;
}

SGD::Point Line::GetStartPoint()
{
	return point0;
}

SGD::Point Line::GetEndPoint()
{
	return point1;
}

void Line::SetStartPoint(SGD::Point point)
{
	point0 = point;
}

void Line::SetEndPoint(SGD::Point point)
{
	point1 = point;
}